﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using BeatEmUp.HUD;
using System.Diagnostics;

namespace BeatEmUp.Characters.Enemies
{
    class Boss : Enemies
    {
        public Boss(int playerLevel, Rectangle startingPosition, Texture2D pTextureL, Texture2D pTextureR, GameTime gameTime) :
            base(playerLevel,startingPosition, pTextureL, pTextureR, gameTime)
        {
            move = new EnemiesMovementManager(startingPosition);
            characterHP = new HPDisplay(new Vector2(startingPosition.X, startingPosition.Y), new Vector2(70, 12));
            stats.hp = 100;
            stats.maxHp = 100;
            stats.strenght = 1;
            stats.luck = 1;
            stats.level = playerLevel;
            isAttacking = false;
            for (int i = 1; i < playerLevel + 5; i++)
                stats.LevelUp();
            Debug.WriteLine("Enemy level: " + stats.level);
        }

        public void SetPosition(Rectangle set)
        {
            (move as EnemiesMovementManager).Position = set;
            UpdateCollisionRec();
        }

        public void MoveEnemy(int value)
        {
            Rectangle set = GetPosition();
            set.X += value;
            SetPosition(set);
        }

        public Rectangle GetPosition()
        {
            return (move as EnemiesMovementManager).Position;
        }

        internal void MoveToPlayer(Rectangle playerCollision, Player player)
        {
            if (!collisionRec.Intersects(playerCollision))
            {

                if (CollisionRec.X > playerCollision.X)
                {
                    (move as EnemiesMovementManager).getCloser(MoveEnum.Left);
                }
                if (CollisionRec.X < playerCollision.X)
                {
                    (move as EnemiesMovementManager).getCloser(MoveEnum.Right);
                }
                if (CollisionRec.Y > playerCollision.Y)
                {
                    (move as EnemiesMovementManager).getCloser(MoveEnum.Up);
                }
                if (CollisionRec.Y < playerCollision.Y)
                {
                    (move as EnemiesMovementManager).getCloser(MoveEnum.Down);
                }

                UpdateCollisionRec();

            }
            if (!player.IsAttacked)
            {
                if (player.getFaceDirection() == FaceDirectionEnum.Left)
                {
                    CheckPlayerAttack(playerCollision, player);

                }
                if (player.getFaceDirection() == FaceDirectionEnum.Right)
                {
                    CheckPlayerAttack(playerCollision, player);
                }
            }
        }

        public void CheckPlayerAttack(Rectangle playerCollision, Player player)
        {
            if (!isAttacking)
            {
                if (MovedRectangle(CollisionRec, 30).Intersects(playerCollision))
                {
                    SoundManager.PlayerInjuredSound();
                    player.Damage(5 + rand.Next(stats.strenght));
                    previousRectangle = GetPosition();
                    SetPosition(MovedRectangle(GetPosition(), 30));
                    isAttacking = true;
                }
                if (MovedRectangle(CollisionRec, -30).Intersects(playerCollision))
                {
                    SoundManager.PlayerInjuredSound();
                    player.Damage(5 + rand.Next(stats.strenght));
                    previousRectangle = GetPosition();
                    SetPosition(MovedRectangle(GetPosition(), 30));
                    isAttacking = true;
                }
            }
        }

        public Rectangle MovedRectangle(Rectangle rect, int value)
        {
            return new Rectangle(rect.X + value, rect.Y, rect.Width, rect.Height);
        }

        //Walka i obrażenia - staby i metody - później wymagana bedzie osobna klasa tak, zeby można to wykorzystać i do postaci
        bool isAttacked = false;
        float damageTimeRemaining;
        float damageAnimationTotalTime = 500;
        int attackDelay = 0;
        Rectangle previousRectangle;
        Random rand = new Random();

        public int GetLevel()
        {
            return stats.level;
        }

        public float Damage(float weaponDamage)
        {
            isAttacked = true;
            if (stats.hp > 0) stats.hp -= (int)Math.Round(weaponDamage, MidpointRounding.ToEven);//Tutaj będzie to wyliczane ze statystyk przeciwnika
            if (stats.hp < 0 && stats.hp != -1) stats.hp = -1;
            damageTimeRemaining = damageAnimationTotalTime;
            return weaponDamage;
        }
        public void Update(GameTime gameTime)//Wykorzystywane tylko do zmniejszenia czasu podświetlenia i sprawdzania tego czy jest atakowany
        {
            if (isAttacked)
            {
                damageTimeRemaining = MathHelper.Max(0, damageTimeRemaining - (float)gameTime.ElapsedGameTime.TotalMilliseconds);
                if (damageTimeRemaining == 0)
                {
                    isAttacked = false;
                    if (stats.hp == -1) stats.hp = 0;
                }
            }
            if (isAttacking)
            {
                attackDelay++;
                if (attackDelay == 4)
                {
                    SetPosition(previousRectangle);
                    attackDelay = 0;
                    isAttacking = false;
                }
            }
            characterHP.UpdatePosition(new Vector2(GetPosition().X, GetPosition().Y - 16));
        }

        public void Draw(SpriteBatch sb)//Metoda draw jest wymagana, aby wyświetlić też hp przeciwnika
        {
            GameManager.customResolution.Draw(CharacterTexture, GetPosition(), TextureColor);
            characterHP.Draw(sb, HPPercentage(), stats.level);
        }

        public Color TextureColor//Właściwość zwracająca kolor czerwony jezeli jest przeciwnik atakowany, czarny jezeli zginal i bialy żeby wyrysowac normalnie
        {
            get
            {
                if (stats.hp == -1 && damageTimeRemaining > 0)
                {
                    if (characterHP.IsDisplayed != false)
                        characterHP.IsDisplayed = false;
                    return Color.Black;
                }
                if (damageTimeRemaining > 0)
                    return Color.Red;
                return Color.White;
            }
        }

        public bool IsAttacked
        {
            set { isAttacked = value; }
            get { return isAttacked; }
        }

    }
}
